package com.bwstudio.demo.provider.service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.bwstudio.demo.provider.dao.AccountInfoDao;
import com.bwstudio.demo.provider.entity.AccountInfo;
import com.bwstudio.demo.provider.model.AccountChangeEvent;
import com.bwstudio.demo.provider.model.NewAccountChangeEvent;
import com.google.gson.Gson;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.apache.rocketmq.spring.support.RocketMQHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.UUID;

/**
 * @author buwei
 */
@Service
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class NewAccountInfoServiceImpl implements NewAccountInfoService {

	private final AccountInfoDao accountInfoDao;

	private final RocketMQTemplate rocketMQTemplate;


	@Override
	public void transfer(AccountChangeEvent accountChangeEvent) {
		AccountInfo accountInfoFrom = accountInfoDao.selectOne(
				Wrappers.<AccountInfo>lambdaQuery()
						.eq(AccountInfo::getAccountNo, accountChangeEvent.getAccountNo()));
		if(accountInfoFrom == null){
			throw new IllegalArgumentException("转出账户:" +accountChangeEvent.getAccountNo()+"不存在");
		}

		Gson gson = new Gson();
		String msgJson = gson.toJson(accountChangeEvent);

		rocketMQTemplate.sendMessageInTransaction(
				"topic_txmsg:new",
				MessageBuilder.withPayload(msgJson)
						.setHeader(RocketMQHeaders.TRANSACTION_ID, accountChangeEvent.getTxNo())
						.setHeader("accountInfo_id",accountInfoFrom.getId())
						.build(),
				accountInfoFrom
		);
	}

	// 更新账户，扣减金额
	@Override
	@Transactional(rollbackFor = RuntimeException.class)
	public void doReduceAccountBalance(AccountChangeEvent accountChangeEvent) {
		// 幂等判断
		if (accountInfoDao.isExistTx(accountChangeEvent.getTxNo()) > 0) {
			return;
		}
		// 扣减金额
		accountInfoDao.updateAccountBalance(accountChangeEvent.getAccountNo(), accountChangeEvent.getAmount().multiply(new BigDecimal(-1)));
		// 添加事务日志
		accountInfoDao.addTx(accountChangeEvent.getTxNo());
		if (accountChangeEvent.getAmount().compareTo(new BigDecimal(3)) == 0) {
			throw new RuntimeException("人为制造异常");
		}
	}
}